### Project 33: Ultrasonic Radar ![](media/19a7c30e24f0ec39da94912c5535b791.png) **1. Description** ![](media/38037219a4908755dbedc422be1ab61b.jpeg) We know that bats use echoes to determine the direction and the location of their preys. In real life, sonar is used to detect sounds in the water. Since the attenuation rate of electromagnetic waves in water is very high, it cannot be used to detect signals, however, the attenuation rate of sound waves in the water is much smaller, so sound waves are most commonly used underwater for observation and measurement. In this experiment, we will use a speaker module, an RGB module and a 4-digit tube display to make a device for detection through ultrasonic. **2. Required Components** ![image-20231020085745428](media/image-20231020085745428.png) **3. Connection Diagram** ![](media/3d6e86b75df96354e05447244d2fee68.png) **4. Test Code** ```Python from machine import Pin, PWM import utime # definitions for TM1650 ADDR_DIS = 0x48 #mode command ADDR_KEY = 0x49 #read key value command # definitions for brightness BRIGHT_DARKEST = 0 BRIGHT_TYPICAL = 2 BRIGHTEST = 7 on = 1 off = 0 # number:0~9 NUM = [0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f] # DIG = [0x68,0x6a,0x6c,0x6e] DIG = [0x6e,0x6c,0x6a,0x68] DOT = [0,0,0,0] clkPin = 22 dioPin = 21 clk = Pin(clkPin, Pin.OUT) dio = Pin(dioPin, Pin.OUT) DisplayCommand = 0 def writeByte(wr_data): global clk,dio for i in range(8): if(wr_data & 0x80 == 0x80): dio.value(1) else: dio.value(0) clk.value(0) utime.sleep(0.0001) clk.value(1) utime.sleep(0.0001) clk.value(0) wr_data <<= 1 return def start(): global clk,dio dio.value(1) clk.value(1) utime.sleep(0.0001) dio.value(0) return def ack(): global clk,dio dy = 0 clk.value(0) utime.sleep(0.0001) dio = Pin(dioPin, Pin.IN) while(dio.value() == 1): utime.sleep(0.0001) dy += 1 if(dy>5000): break clk.value(1) utime.sleep(0.0001) clk.value(0) dio = Pin(dioPin, Pin.OUT) return def stop(): global clk,dio dio.value(0) clk.value(1) utime.sleep(0.0001) dio.value(1) return def displayBit(bit, num): global ADDR_DIS if(num > 9 and bit > 4): return start() writeByte(ADDR_DIS) ack() writeByte(DisplayCommand) ack() stop() start() writeByte(DIG[bit-1]) ack() if(DOT[bit-1] == 1): writeByte(NUM[num] | 0x80) else: writeByte(NUM[num]) ack() stop() return def clearBit(bit): if(bit > 4): return start() writeByte(ADDR_DIS) ack() writeByte(DisplayCommand) ack() stop() start() writeByte(DIG[bit-1]) ack() writeByte(0x00) ack() stop() return def setBrightness(b = BRIGHT_TYPICAL): global DisplayCommand,brightness DisplayCommand = (DisplayCommand & 0x0f)+(b<<4) return def setMode(segment = 0): global DisplayCommand DisplayCommand = (DisplayCommand & 0xf7)+(segment<<3) return def displayOnOFF(OnOff = 1): global DisplayCommand DisplayCommand = (DisplayCommand & 0xfe)+OnOff return def displayDot(bit, OnOff): if(bit > 4): return if(OnOff == 1): DOT[bit-1] = 1; else: DOT[bit-1] = 0; return def InitDigitalTube(): setBrightness(2) setMode(0) displayOnOFF(1) for _ in range(4): clearBit(_) return def ShowNum(num): #0~9999 displayBit(1,num%10) if(num < 10): clearBit(2) clearBit(3) clearBit(4) if(num > 9 and num < 100): displayBit(2,num//10%10) clearBit(3) clearBit(4) if(num > 99 and num < 1000): displayBit(2,num//10%10) displayBit(3,num//100%10) clearBit(4) if(num > 999 and num < 10000): displayBit(2,num//10%10) displayBit(3,num//100%10) displayBit(4,num//1000) pwm_r = PWM(Pin(0)) pwm_g = PWM(Pin(2)) pwm_b = PWM(Pin(15)) pwm_r.freq(1000) pwm_g.freq(1000) pwm_b.freq(1000) def light(red, green, blue): pwm_r.duty(red) pwm_g.duty(green) pwm_b.duty(blue) # Ultrasonic ranging, unit: cm def getDistance(trigger, echo): # Generates a 10us square wave trigger.value(0) #A short low level is given beforehand to ensure a clean high pulse: utime.sleep_us(2) trigger.value(1) utime.sleep_us(10)#After pulling high, wait 10 microseconds and immediately set it to low trigger.value(0) while echo.value() == 0: #Establish a while loop to detect whether the echo pin value is 0 and record the time at that time start = utime.ticks_us() while echo.value() == 1: #Establish a while loop to check whether the echo pin value is 1 and record the time at that time end = utime.ticks_us() d = (end - start) * 0.0343 / 2 #The travel time of the sound wave x the speed of sound (343.2 m/s, 0.0343 cm/microsecond), and the distance back and forth divided by 2. return d # set the pin trigger = Pin(13, Pin.OUT) echo = Pin(14, Pin.IN) buzzer = PWM(Pin(18)) def playtone(frequency): buzzer.duty(1000) buzzer.freq(frequency) def bequiet(): buzzer.duty(0) # main program InitDigitalTube() while True: distance = int(getDistance(trigger, echo)) ShowNum(distance) if distance <= 10: playtone(880) utime.sleep(0.1) bequiet() light(1023, 0, 0) elif distance <= 20: playtone(532) utime.sleep(0.2) bequiet() light(0, 0, 1023) else: light(0, 1023, 0) ``` **5. Code Explanation** We set sound frequency and light color by adjusting different distance range. We can adjust the distance range in the code. **6. Test Result** Connect the wires according to the experimental wiring diagram and power on. Click ![](media/da852227207616ccd9aff28f19e02690.png)“Run current script”, the code starts executing. When the ultrasonic sensor detects different distances(within 20 cm), the buzzer will produce different frequencies of sound, the RGB will show different colors, and the measured distances are displayed on the 4-digit tube display. Press “Ctrl+C”or click ![](media/27451c8a9c13e29d02bc0f5831cfaf1f.png)“Stop/Restart backend”to exit the program.